package client

import (
	"bytes"
	"context"
	"fmt"
	"log"

	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
)

var client *minio.Client

const (
	MINIO_SERVER             = "172.31.51.101:9000"
	SECURE              bool = false
	ACCESS_KEY_ID            = "minio"
	ACCESS_KEY_PASSWORD      = "minio123"
)

func init() {
	client = newClient()
}

func CreateBucket(ctx context.Context, name string) error {
	err := client.MakeBucket(ctx, name, minio.MakeBucketOptions{})
	if err != nil {
		bucketExists, _ := client.BucketExists(ctx, name)
		if bucketExists {
			log.Printf("Waring: bucketname %s is exists", name)
			return nil
			// return errors.New("bucket exists")
		}
		return err
	} else {
		return nil
	}
}

func MakeBucketAccess(ctx context.Context, bucketName string) error {
	return client.SetBucketPolicy(ctx, bucketName, "public")
}

func GetBucketPolicy(ctx context.Context, bucketName string) (string, error) {
	return client.GetBucketPolicy(ctx, bucketName)
}

func Upload(ctx context.Context, bucketName string, fe *FileEntry) (minio.UploadInfo, error) {
	return client.PutObject(ctx, bucketName, fe.FileName, fe.Reader(), int64(fe.Size()), minio.PutObjectOptions{})

}

func createUrl(fi *minio.UploadInfo) string {
	sechema := "http"
	if SECURE {
		sechema = "https"
	}
	return fmt.Sprintf("%s://%s/%s/%s", sechema, MINIO_SERVER, fi.Bucket, fi.Key)
}

// 也可用：go get github.com/gabriel-vasile/mimetype 这个包获取content-type
func UploadReturnUrl(ctx context.Context, bucketName string, fe *FileEntry) (string, error) {
	fi, err := client.PutObject(ctx, bucketName, fe.FileName, fe.Reader(), int64(fe.Size()), minio.PutObjectOptions{ContentType: fe.ContentType()})
	if err != nil {
		return "", err
	}
	return createUrl(&fi), err
}

func Download(ctx context.Context, bucketName string, objectName string) ([]byte, error) {
	obj, err := client.GetObject(ctx, bucketName, objectName, minio.GetObjectOptions{})
	if err != nil {
		return nil, err
	}
	bf := bytes.Buffer{}
	bf.ReadFrom(obj)
	return bf.Bytes(), err
}

func newClient() *minio.Client {
	// endpoint := "172.31.51.101:9000"
	// accessKeyID := "minio"
	// secretAccessKey := "minio123"
	// useSSL := false

	// Initialize minio client object.
	minioClient, err := minio.New(MINIO_SERVER, &minio.Options{
		Creds:  credentials.NewStaticV4(ACCESS_KEY_ID, ACCESS_KEY_PASSWORD, ""),
		Secure: SECURE,
	})
	if err != nil {
		log.Fatalln(err)
	}
	return minioClient

	// log.Printf("%#v\n", minioClient) // minioClient is now set up
}
